%------------------------------------------------------------------
%------------------------------------------------------------------
%   Author: Md. Sazzad Hussain (sazzad.hussain@sydney.edu.au)
%   Learning and Affect Technologies Engineering (LATTE)
%   University of Sydney, 2011
%------------------------------------------------------------------
%------------------------------------------------------------------

function varargout = siento_biosigInspector_IAPS(varargin)
% SIENTO_BIOSIGINSPECTOR_IAPS M-file for siento_biosigInspector_IAPS.fig
%      SIENTO_BIOSIGINSPECTOR_IAPS, by itself, creates a new SIENTO_BIOSIGINSPECTOR_IAPS or raises the existing
%      singleton*.
%
%      H = SIENTO_BIOSIGINSPECTOR_IAPS returns the handle to a new SIENTO_BIOSIGINSPECTOR_IAPS or the handle to
%      the existing singleton*.
%
%      SIENTO_BIOSIGINSPECTOR_IAPS('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in SIENTO_BIOSIGINSPECTOR_IAPS.M with the given input arguments.
%
%      SIENTO_BIOSIGINSPECTOR_IAPS('Property','Value',...) creates a new SIENTO_BIOSIGINSPECTOR_IAPS or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before siento_biosigInspector_IAPS_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to siento_biosigInspector_IAPS_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help siento_biosigInspector_IAPS

% Last Modified by GUIDE v2.5 14-Sep-2011 18:08:42

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @siento_biosigInspector_IAPS_OpeningFcn, ...
                   'gui_OutputFcn',  @siento_biosigInspector_IAPS_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before siento_biosigInspector_IAPS is made visible.
function siento_biosigInspector_IAPS_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to siento_biosigInspector_IAPS (see VARARGIN)
global myTimer;

%pixels
set( gcf, 'Units', 'pixels' );
%get your display size
screenSize = get(0, 'ScreenSize');
%calculate the center of the display
position = get(gcf, 'Position' );
position(1) = (screenSize(3)-position(3))/2;
position(2) = (screenSize(4)-position(4))/2;
%center the window
set( gcf,'Position', position );

set(handles.pushbutton_next,'enable','off');
set(handles.pushbutton_prev,'enable','off');
set(handles.checkbox_comment,'enable','off');
set(handles.checkbox_comment,'value',0);
set(handles.edit_comment,'enable','off');
set(handles.axes1,'visible', 'off');
set(handles.axes2,'visible', 'off');
set(handles.axes3,'visible', 'off');
set(handles.axes4,'visible', 'off');
set(handles.axes5,'visible', 'off');
% Choose default command line output for siento_biosigInspector_IAPS
handles.output = hObject; 

%initialize video
pos=[10 240 360 350];%position of the video frame in the form
linkSource = 'linkFile.txt';
%media player 
MovieControl = actxcontrol('WMPlayer.OCX',pos)
set(MovieControl,'uiMode','none');
MovieControl.controls.events
assignin('base','MovieControl',MovieControl);
set(MovieControl.settings,'autoStart',0);
set(MovieControl.controls,'CurrentPosition',0);
set(MovieControl,'enableContextMenu',0);
set(MovieControl,'enabled',0);
set(MovieControl,'uiMode','full');
handles.MovieControl = MovieControl;

set(handles.siento_biosigInspector,'CloseRequestFcn',@closeGUI);%for closing function
handles.dataLinkdata = importdata(linkSource);
sID=handles.dataLinkdata;
set(handles.popupmenu_sid,'String',sID);

%init the timer
myTimer=timer;
set(myTimer,'executionMode','fixedRate');

guidata(hObject, handles);    

% --- Outputs from this function are returned to the command line.
function varargout = siento_biosigInspector_IAPS_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

function closeGUI(src,evnt)
%src is the handle of the object generating the callback (the source of the event)
%evnt is the The event data structure (can be empty for some callbacks)
selection = questdlg('Do you want to exit BioSignal Inspector?',...
    'Close Request Function',...
    'Yes','No','Yes');
global T;
switch selection,
    case 'Yes',
        delete(gcf);
        delete(T);
        clear all;
    case 'No'
        return
end

function linkData(hObject,handles,subjectID)
global indir;
filesPath=indir;
filesDir=dir(filesPath);%dir info for files path
lenName=length(char(subjectID));
handles.subjectID=subjectID;

for m=1:length(filesDir)
    [path,name,ext,ver] = fileparts(filesDir(m).name);
    if strncmp(subjectID,name,lenName)%choose only selected subject
        if strcmp(ext,'.mat')%.mat files
            loadPhysio=[filesPath '\' name ext];%.mat physio path
            physioSplit= regexp(name,'_','split');
            physioATS=physioSplit(:,5);%physio abs time stamp
        elseif strcmp(ext, '.txt')%.txt files
            loadAnn=[filesPath '\' name ext];%.txt annotation path
        elseif strcmp(ext,'.wmv');
            loadVid=[filesPath '\' name ext];%.wmv videopath
            vidSplit= regexp(name,'_','split');
            vidATS=vidSplit(:,5);%video abs time stamp
        end
    end
end
handles.loadPhysio=loadPhysio;
handles.loadAnn=loadAnn;
handles.loadVid=loadVid;
handles.physioATS=physioATS;
handles.vidATS=vidATS;
handles.count=1;%initial instnace

set(handles.pushbutton_prev,'enable','off');
set(handles.axes1,'visible', 'on');
set(handles.axes2,'visible', 'on');
set(handles.axes3,'visible', 'on');
set(handles.axes4,'visible', 'on');
set(handles.axes5,'visible', 'on');

load(loadPhysio);%the all physiological channels
% handles.ecgCH = bio_cleaner(1000,80,1,data(:,1));
% handles.gsrCH = bio_cleaner(1000,10,0.05,data(:,2));

%GSR preprocessing
% dataGSR = data(:,2);%raw gsr
dataGSR = aubt_lowpassFilter (data(:,2), 1000, 0.3);
dataGSR = aubt_scBaseline (dataGSR);
minGSR=min(dataGSR);
dataGSR=dataGSR+abs(minGSR);%baseline correction

handles.ecgCH = data(:,1);%ECG
handles.gsrCH = dataGSR;%GSR (processed)
rawEMG1 = data(:,3);%emg1 (Corrugator)
XD1 = bio_cleaner(1000,80,1,rawEMG1);
handles.EMGCH1=XD1;
rawEMG2 = data(:,5);%emg2 (Zygomatic)
XD2 =  bio_cleaner(1000,80,1,rawEMG2);
handles.EMGCH2=XD2;
handles.respCH= data(:,6);%respiration

fid = fopen(loadAnn);%load annotation
C = textscan(fid,'%s%s%s%s%f%s','delimiter', ',');
fclose(fid);
lenFile=length(C{1}(:,1));

%extract from self report
normRating=C{2}(2:(lenFile-1));%norm rating col
selfRating=C{5}(2:(lenFile-1));%self rating col
startT=C{3}(2:(lenFile-1));%start of task

%handles
handles.lenFile=lenFile;
handles.normRating=normRating; %normative
handles.selfRating=selfRating; %SR
handles.startT=startT; %start of task

%call load data function
loadData(hObject,handles);

function loadData(hObject,handles)
global myTimer;
stop(myTimer);

%object handles
set(handles.pushbutton_next,'enable','on');
set(handles.checkbox_comment,'enable','on');
set(handles.checkbox_comment,'value',0);
set(handles.edit_comment,'enable','on');
set(handles.edit_comment,'string','');

%handles
ecgCH=handles.ecgCH;
gsrCH=handles.gsrCH;
respCH=handles.respCH;
EMGCH1=handles.EMGCH1;
EMGCH2=handles.EMGCH2;

normRating=handles.normRating; %normative
selfRating=handles.selfRating; %SR
startT=handles.startT; %start of task
lenFile=handles.lenFile;

loadPhysio=handles.loadPhysio;
loadAnn=handles.loadAnn;
loadVid=handles.loadVid;
physioATS=handles.physioATS;
vidATS=handles.vidATS;
k=handles.count;
set(handles.text_index,'string',k);
Absolute_Time = datenum(physioATS, 'HH-MM-SS')*24*60*60; %physio ABS in seconds
nsRate=1000;
physioInterval=10;

%video indexing
Start_Vid=datenum(startT(k), 'HH:MM:SS')*24*60*60;
Absolute_VidTime = datenum(vidATS, 'HH-MM-SS')*24*60*60; %video ABS in seconds
Start_VidIndex = (Start_Vid - Absolute_VidTime);
Start_VidIndex=ceil(Start_VidIndex);
mp = handles.MovieControl;
mp.URL=loadVid;
set(mp.controls,'CurrentPosition',Start_VidIndex);
set(mp,'enabled',1);
mp.controls.play;

%extracting theoretical categories
splitCat=regexp(normRating(k),'_','split');
valCat=splitCat{:}(2);%valence
arCat=splitCat{:}(3);%arousal
dimCat=strcat(valCat,'-',arCat);%dim (write this)

%extracting self reports
switch selfRating(k)
    case 1
        dimSelf={'MediumValence-LowArousal'};
    case 2
        dimSelf={'HighValence-LowArousal'};
    case 3
        dimSelf={'MediumValence-MediumArousal'};
    case 4
        dimSelf={'HighValence-MediumArousal'};
    case 5
        dimSelf={'HighValence-HighArousal'};
    case 6
        dimSelf={'MediumValence-HighArousal'};
    case 7
        dimSelf={'LowValence-HighArousal'};
    case 8
        dimSelf={'LowValence-MediumArousal'};
    case 9
        dimSelf={'LowValence-LowArousal'};
end
dimCat=strcat('NR: ',dimCat);
dimSelf=strcat('SR: ', dimSelf);
%set text_emotionTag
set(handles.text_emotionTag,'string',[dimCat dimSelf]);
set(handles.text_emotionTag,'ForegroundColor','black');

%physio indexing
Start_Trial = Start_Vid; % in seconds
Start_Index = (Start_Trial - Absolute_Time) * nsRate; %--> (changed sample rate) start time
End_IndexECG = (Start_Index + physioInterval * nsRate)-1;%-->(changed sample rate) end time for ecg window
End_IndexGSR = (Start_Index + physioInterval * nsRate)-1;%-->(changed sample rate) end time for gsr window
End_IndexEMG1 = (Start_Index + physioInterval * nsRate)-1;%-->(changed sample rate) end time for emg1 window
End_IndexEMG2 = (Start_Index + physioInterval * nsRate)-1;%-->(changed sample rate) end time for emg2 window
End_IndexResp = (Start_Index + physioInterval * nsRate)-1;%-->(changed sample rate) end time for resp window

Trial_ChunkECG = ecgCH(Start_Index:End_IndexECG); %trial chunk
Trial_ChunkGSR = gsrCH(Start_Index:End_IndexGSR); %trial chunk
Trial_ChunkEMG1 = EMGCH1(Start_Index:End_IndexEMG1); %trial chunk
Trial_ChunkEMG2 = EMGCH2(Start_Index:End_IndexEMG2); %trial chunk
Trial_ChunkResp = respCH(Start_Index:End_IndexResp); %trial chunk

%ECG Feat
rind = aubt_detecR (Trial_ChunkECG, nsRate);
% convert rr intervals to heart rate
rrintervals = diff (double (rind)) ./ nsRate;
hrv = 60./rrintervals;  % beats per minute

%GSR Feat
meanGSR=mean (Trial_ChunkGSR);

%EMG Feat
meanEMG1=mean(Trial_ChunkEMG1);
meanEMG2=mean(Trial_ChunkEMG2);

%resp Feat
data = aubt_lowpassFilter (Trial_ChunkResp, nsRate, 0.45);
pulse = downsample (aubt_getPulseFreq (aubt_getMaxima (data), nsRate), nsRate);
bpm=pulse.*60;%breath rate

axes(handles.axes1);
ecg = Trial_ChunkECG;
ecgTime = 1/nsRate : 1/nsRate : (length(ecg)/nsRate);
ecgPlot = plot(ecgTime,ecg);
set(ecgPlot,'Color','red')
title(['ECG']);% (hrv): ' num2str(mean(hrv))]);
set(gca,'xtick',[]);
%set(gcf,'doublebuffer','on');
set(gca,'xlim',[0 physioInterval]);
set(gca,'ylim',[min(ecg) max(ecg)]);
% ecgTimeMin=Start_Index;
% set(gca,'xlim',[ecgTimeMin (ecgTimeMin+physioInterval * nsRate)]);

axes(handles.axes2);
sc = Trial_ChunkGSR;
scTime = 1/nsRate : 1/nsRate : (length(sc)/nsRate);
scPlot = plot(scTime,sc);
set(scPlot,'Color','blue')
title(['GSR']);% (mean): ' num2str(meanGSR)]);
set(gca,'xtick',[]);
%set(gcf,'doublebuffer','on');
set(gca,'xlim',[0 physioInterval]);
set(gca,'ylim',[min(sc) max(sc)]);
% scTimeMin=startPhysio;
% set(gca,'xlim',[scTimeMin scTimeMin+physioInterval]);

axes(handles.axes3);
resp = Trial_ChunkResp;
respTime = 1/nsRate : 1/nsRate : (length(resp)/nsRate);
respPlot = plot(respTime,resp);
set(respPlot,'Color','red')
title(['Resp']);% (bpm): ' num2str(mean(bpm))]);
set(gca,'xtick',[]);
%set(gcf,'doublebuffer','on');
set(gca,'xlim',[0 physioInterval]);
set(gca,'ylim',[min(resp) max(resp)]);
% respTimeMin=startPhysio;
% set(gca,'xlim',[respTimeMin respTimeMin+physioInterval]);

axes(handles.axes4);
emg1 = Trial_ChunkEMG1;
emg1Time = 1/nsRate : 1/nsRate : (length(resp)/nsRate);
emg1Plot = plot(emg1Time,emg1);
set(respPlot,'Color','red')
title(['EMG-Corr']);% (mean): ' num2str(mean(meanEMG1))]);
set(gca,'xtick',[]);
%set(gcf,'doublebuffer','on');
set(gca,'xlim',[0 physioInterval]);
set(gca,'ylim',[min(emg1) max(emg1)]);
% respTimeMin=startPhysio;
% set(gca,'xlim',[respTimeMin respTimeMin+physioInterval]);

axes(handles.axes5);
emg2 = Trial_ChunkEMG2;
emg2Time = 1/nsRate : 1/nsRate : (length(emg2)/nsRate);
emg2Plot = plot(respTime,emg2);
set(emg2Plot,'Color','blue')
title(['EMG-Zyg']);% (mean): ' num2str(mean(meanEMG2))]);
% set(gca,'xtick',[]);
%set(gcf,'doublebuffer','on');
set(gca,'xlim',[0 physioInterval]);
set(gca,'ylim',[min(emg2) max(emg2)]);
% respTimeMin=startPhysio;
% set(gca,'xlim',[respTimeMin respTimeMin+physioInterval]);

handles.period=physioInterval;
vidStart=get(mp.controls,'CurrentPosition');
handles.vidStart=vidStart;
myTimer.TimerFcn = {@timer_Callback, handles};
start(myTimer);

guidata(hObject, handles);    

function timer_Callback(obj, event, handles)
global myTimer;
mp = handles.MovieControl;
vidCurr=get(mp.controls,'CurrentPosition');
if vidCurr>=(handles.period+handles.vidStart)
    mp.controls.pause;
    stop(myTimer);
end

% --- Executes on selection change in popupmenu_sid.
function popupmenu_sid_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu_sid (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupmenu_sid contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_sid
selectedIndex = get(handles.popupmenu_sid,'Value');
if (selectedIndex == 1) 
   return;
end
selected = get(handles.popupmenu_sid,'String');
linkData(hObject,handles,selected(selectedIndex));

% --- Executes during object creation, after setting all properties.
function popupmenu_sid_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu_sid (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in pushbutton_next.
function pushbutton_next_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_next (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%update instance
global myTimer;
stop(myTimer);
set(handles.pushbutton_prev,'enable','on');
if handles.count==length(handles.startT)
    set(handles.pushbutton_next,'enable','off');
    set(handles.checkbox_comment,'enable','off');
    set(handles.checkbox_comment,'value',0);
    set(handles.edit_comment,'enable','off');
    msgbox('End of Session');
else
    count=handles.count+1;
    handles.count=count;
    loadData(hObject,handles);
end

% --- Executes on button press in pushbutton_prev.
function pushbutton_prev_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_prev (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%update instance
global myTimer;
stop(myTimer);
if handles.count>1
    count=handles.count-1;
    handles.count=count;
    loadData(hObject,handles);
elseif handles.count
    set(handles.pushbutton_prev,'enable','off');
end

function edit_comment_Callback(hObject, eventdata, handles)
% hObject    handle to edit_comment (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_comment as text
%        str2double(get(hObject,'String')) returns contents of edit_comment as a double


% --- Executes during object creation, after setting all properties.
function edit_comment_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_comment (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in checkbox_comment.
function checkbox_comment_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox_comment (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox_comment
global outdir;
sub_ID=handles.subjectID;
k=handles.count;
Start_Time=handles.startT;
boxVal=get(handles.checkbox_comment,'value');
mkdir(outdir);

if boxVal==1       
    %write to file
    fid=fopen([outdir '\' char(sub_ID) '_inspectLog.txt'],'a');%open file    
    fprintf(fid, '%s,', num2str(k));%index number
    fprintf(fid, '%s,', Start_Time{k});%baseline duration
    fprintf(fid, '%s\n', get(handles.edit_comment,'string'));%baseline duration
    fclose(fid);%close file  
    
    set(handles.edit_comment,'string','marked...');        
    pause(0.5);
    set(handles.checkbox_comment,'value',0);
    set(handles.edit_comment,'string','');  
end


% --- Executes on button press in pushbutton_run.
function pushbutton_run_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_run (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on button press in pushbutton52.
function pushbutton52_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton52 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
disp('saz');


% --- Executes on button press in pushbutton53.
function pushbutton53_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton53 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on button press in pushbutton54.
function pushbutton54_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton54 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
